#include "uartcfg.h"
#include "ui_uartcfg.h"

uartCfg::uartCfg(QWidget *parent) : QDialog(parent), ui(new Ui::uartCfg) {
  qRegisterMetaType<comcfg_t>("comcfg_t");
  ui->setupUi(this);
  this->setWindowTitle("串口配置");

  ui->comBox->addItems(getComNum());

  /* 刷新串口 */
  flushCom = new QTimer(this);
  flushCom->setInterval(700);
  connect(flushCom, &QTimer::timeout, this, &uartCfg::flushComList);
  flushCom->start();

  /* 绑定流控信号槽 */
  connect(ui->ctrlHard, &QRadioButton::released, this,
          &uartCfg::selectFlowCtrl);
  connect(ui->ctrlNone, &QRadioButton::released, this,
          &uartCfg::selectFlowCtrl);
  connect(ui->ctrlSoft, &QRadioButton::released, this,
          &uartCfg::selectFlowCtrl);
  ui->ctrlNone->setEnabled(true);

  /* 增加 combobox最后一栏可编辑 */
  QLineEdit *baundBoxEdit = new QLineEdit(this);
  baundBoxEdit->setReadOnly(true);
  baundBoxEdit->setPlaceholderText("自定义");
  ui->baundBox->setLineEdit(baundBoxEdit);
  QRegExp regExp("^[0-9]*[1-9][0-9]*$");
  baundBoxEdit->setValidator(new QRegExpValidator(regExp, this));
  connect(ui->baundBox, SIGNAL(currentIndexChanged(int)), this,
          SLOT(changedBaundIndex(int)));
}

uartCfg::~uartCfg() {
  delete flushCom;
  delete ui;
}

void uartCfg::changedBaundIndex(int index) {
  QComboBox *baundBox = static_cast<QComboBox *>(sender());
  if (0 == index) {
    baundBox->lineEdit()->setReadOnly(false);
    baundBox->lineEdit()->clear();
  } else {
    baundBox->lineEdit()->setReadOnly(true);
  }
}

void uartCfg::setUiBaund(quint32 baund) {
  if (-1 == ui->baundBox->findText(QString::number(baund))) {
    ui->baundBox->addItem(QString::number(baund));
  }
  ui->baundBox->setCurrentIndex(ui->baundBox->findText(QString::number(baund)));
}
void uartCfg::setUiDataBits(QSerialPort::DataBits da) {
  if (-1 == ui->datasBox->findText(QString::number(da))) {
  } else {
    ui->datasBox->setCurrentIndex(ui->datasBox->findText(QString::number(da)));
  }
}
void uartCfg::setUiStopBits(QSerialPort::StopBits da) {
  if (-1 == ui->stopsBox->findText(QString::number(da))) {
  } else {
    ui->stopsBox->setCurrentIndex(ui->stopsBox->findText(QString::number(da)));
  }
}
void uartCfg::setUiParityBits(QSerialPort::Parity da) {
  if (-1 == ui->paritysBox->findText(QString::number(da))) {
  } else {
    ui->paritysBox->setCurrentIndex(
        ui->paritysBox->findText(QString::number(da)));
  }
}
void uartCfg::setUiFlowBits(QSerialPort::FlowControl da) {
  switch (da) {
  case QSerialPort::HardwareControl:
    ui->ctrlHard->setChecked(true);
    break;
  case QSerialPort::SoftwareControl:
    ui->ctrlSoft->setChecked(true);
    break;
  case QSerialPort::NoFlowControl:
  default:
    ui->ctrlNone->setChecked(true);
    break;
  }
}

void uartCfg::setCfgPtr(comcfg_t cfg) {
  curCfg.portNum = cfg.portNum;
  curCfg.baudRate = cfg.baudRate;
  curCfg.dataBits = cfg.dataBits;
  curCfg.paritys = cfg.paritys;
  curCfg.stopBits = cfg.stopBits;
  curCfg.flowCtrl = cfg.flowCtrl;
  setUiBaund(cfg.baudRate);
  setUiDataBits(cfg.dataBits);
  setUiStopBits(cfg.stopBits);
  setUiParityBits(cfg.paritys);
  setUiFlowBits(cfg.flowCtrl);
}

QStringList uartCfg::getComNum() {
  QStringList comList;
  QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();
  for (int i = 0; i < serialList.length(); i++) {
    comList << serialList.at(i).portName();
  }
  comList.sort();
  return comList;
}

void uartCfg::flushComList() {
  int index = 0;
  QString comName = ui->comBox->currentText();
  ui->comBox->clear();
  ui->comBox->addItems(getComNum());
  index = ui->comBox->findText(comName);
  if (-1 != index) {
    ui->comBox->setCurrentIndex(index);
    curCfg.portNum = ui->comBox->currentText().toInt();
  }
}

void uartCfg::on_falseButton_clicked() { this->hide(); }

void uartCfg::on_okButton_clicked() {
  if (ui->baundBox->currentText().toUInt() == 0) {
    QMessageBox::information(NULL, "波特率错误:", "波特率不能设置为0");
    return;
  }
  this->hide();
  curCfg.baudRate = ui->baundBox->currentText().toUInt();
  curCfg.portNum = ui->comBox->currentText().split("M").at(1).toInt();
  on_paritysBox_activated(ui->paritysBox->currentIndex());
  on_datasBox_activated(ui->datasBox->currentIndex());
  on_stopsBox_activated(ui->stopsBox->currentIndex());

  emit setUartFinish(curCfg);
}

void uartCfg::on_paritysBox_activated(int index) {
  switch (index) {
  case 0: /* NoParity  */
    curCfg.paritys = QSerialPort::NoParity;
    break;
  case 2: /* OddParity */
    curCfg.paritys = QSerialPort::OddParity;
    break;
  case 3: /* SpaceParity */
    curCfg.paritys = QSerialPort::SpaceParity;
    break;
  case 4: /* MarkParity */
    curCfg.paritys = QSerialPort::MarkParity;
    break;
  case 1: /* EvenParity */
  default:
    curCfg.paritys = QSerialPort::EvenParity;
    break;
  }
}

void uartCfg::on_datasBox_activated(int index) {
  switch (index) {
  case 0: /* 5 */
    curCfg.dataBits = QSerialPort::Data5;
    break;
  case 1: /* 6 */
    curCfg.dataBits = QSerialPort::Data6;
    break;
  case 2: /* 7 */
    curCfg.dataBits = QSerialPort::Data7;
    break;
  case 3: /* 8 */
  default:
    curCfg.dataBits = QSerialPort::Data8;
    break;
  }
}

void uartCfg::on_stopsBox_activated(int index) {
  switch (index) {
  case 1:
    curCfg.stopBits = QSerialPort::OneAndHalfStop;
    break;
  case 2:
    curCfg.stopBits = QSerialPort::TwoStop;
    break;
  case 0:
  default:
    curCfg.stopBits = QSerialPort::OneStop;
    break;
  }
}

void uartCfg::selectFlowCtrl() {
  QRadioButton *curBtn = qobject_cast<QRadioButton *>(QObject::sender());
  if (curBtn->objectName() == "ctrlHard") {
    /* 硬件流控 */
    curCfg.flowCtrl = QSerialPort::HardwareControl;
  } else if (curBtn->objectName() == "ctrlSoft") {
    /* 软件流控 */
    curCfg.flowCtrl = QSerialPort::SoftwareControl;
  } else {
    /* 无 */
    curCfg.flowCtrl = QSerialPort::NoFlowControl;
  }
}

void uartCfg::on_baundBox_activated(const QString &) {
  if (ui->baundBox->currentIndex() != 0) {
    curCfg.baudRate = ui->baundBox->currentText().toUInt();
  }
}
